package search;

import game.AbstractOthelloPosition;
import game.OthelloAction;

import java.util.ArrayList;
import java.util.LinkedList;

public class OthelloSearchNode implements Comparable<OthelloSearchNode>{

	private ArrayList<OthelloSearchNode> _childs;
	private int _utility;
	private AbstractOthelloPosition _position;
	private int _level;
	private OthelloAction _action;

	public OthelloSearchNode(int level, AbstractOthelloPosition position) {
		_utility = 0;
		_level = level;
		_childs = null;
		_action = null;
		_position = position;
	}

	public ArrayList<OthelloSearchNode> getChilds() {
		return _childs;
	}

	public int getUtility() {
		return _utility;
	}

	public void setUtility(int evaluator){
		_utility = evaluator;
	}


	public void setPosition(AbstractOthelloPosition position) {
		_position = position;
	}

	public void addChild(OthelloSearchNode child) {
		_childs.add(child);
	}

	public int getLevel() {
		return _level;
	}

	public AbstractOthelloPosition getPosition() {
		return _position;
	}

	public void setAction(OthelloAction act) {
		_action = act;
	}

	public OthelloAction getAction() {
		return _action;
	}


	public boolean expandNode() {
		if(_childs == null){
			LinkedList<OthelloAction> moves = _position.getMoves();
			if(moves.isEmpty())
				return false;

			_childs = new ArrayList<OthelloSearchNode>();
			while(moves.size() != 0) {
				OthelloAction act = moves.poll();
				AbstractOthelloPosition p = act.apply((AbstractOthelloPosition) _position.clone());
				OthelloSearchNode child = new OthelloSearchNode(_level + 1, p);
				p.changePlayer();
				child.setPosition(p);
				child.setAction(act);
				addChild(child);
			}
		}
		return true;
	}

	public OthelloAction getActionFromUtility(int utility){
		OthelloAction action = null;
		if(getChilds() != null) {
			for(OthelloSearchNode c : getChilds()){
				if(c.getUtility() == utility){
					action = c.getAction();
				}
			}
		}
		return action;
	}

	@Override
	public int compareTo(OthelloSearchNode n) {
		if(_utility < n._utility){
			return -1;
		}else if (_utility == n._utility){
			return 0;
		}else{
			return 1;
		}
	}

	public long nbChildren() {
		// TODO Auto-generated method stub
		if(_childs != null) {
			int nb = 1;
			for(OthelloSearchNode c : _childs) {
				nb += c.nbChildren();
			}
			return nb;
		} else {
			return 1;
		}
	}
}

